﻿using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;

namespace Koala.Pro.Helpers
{
    public static class ControlHelper
    {
        public static void SetDirtyEvent(DependencyObject depObj)
        {
            if (App.ViewModel.DisableDirtyMessage)
            {
                return;
            }
            foreach (TextBoxBase item in FindLogicalChildren<TextBoxBase>(depObj))
            {
                if (item != null && !item.IsReadOnly)
                {
                    item.TextChanged += delegate
                    {
                        MainModelHelper.SetIsDirty();
                    };
                }
            }
            foreach (Selector item2 in FindLogicalChildren<Selector>(depObj))
            {
                Type type = item2.GetType();
                if (item2 != null && item2.IsEnabled && type != typeof(TabControl) && type != typeof(ListBox))
                {
                    item2.SelectionChanged += delegate
                    {
                        MainModelHelper.SetIsDirty();
                    };
                }
            }
            foreach (ToggleButton item3 in FindLogicalChildren<ToggleButton>(depObj))
            {
                if (item3 != null && item3.IsEnabled)
                {
                    item3.Checked += delegate
                    {
                        MainModelHelper.SetIsDirty();
                    };
                    item3.Unchecked += delegate
                    {
                        MainModelHelper.SetIsDirty();
                    };
                }
            }
        }

        public static void SetDirtyWindow(Window window)
        {
            App.ViewModel.IsDirty = false;
            SetDirtyEvent(window);
            window.Closing += delegate (object? s, CancelEventArgs e)
            {
                bool disableDirtyMessage = App.ViewModel.DisableDirtyMessage;
                bool isDirty = App.ViewModel.IsDirty;
                if (!disableDirtyMessage && isDirty)
                {
                    if (MessageDxUtil.ShowYesNoAndWarning("界面控件数据已编辑过，是否确认丢弃并关闭窗口") != MessageBoxResult.Yes)
                    {
                        e.Cancel = true;
                    }
                    else
                    {
                        App.ViewModel.IsDirty = false;
                        GrowlUtil.ClearTips();
                    }
                }
            };
        }

        public static IEnumerable<T> FindLogicalChildren<T>(DependencyObject depObj) where T : DependencyObject
        {
            if (depObj == null)
            {
                yield break;
            }
            foreach (object child2 in LogicalTreeHelper.GetChildren(depObj))
            {
                if (!(child2 is DependencyObject))
                {
                    continue;
                }
                DependencyObject child = (DependencyObject)child2;
                if (child is T val)
                {
                    yield return val;
                }
                foreach (T item in FindLogicalChildren<T>(child))
                {
                    yield return item;
                }
            }
        }

        public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
        {
            if (depObj == null)
            {
                yield break;
            }
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                if (child != null && child is T val)
                {
                    yield return val;
                }
                foreach (T item in FindVisualChildren<T>(child))
                {
                    yield return item;
                }
            }
        }

        public static T FindVisualParent<T>(DependencyObject current) where T : DependencyObject
        {
            for (current = VisualTreeHelper.GetParent(current); current != null; current = VisualTreeHelper.GetParent(current))
            {
                if (current is T result)
                {
                    return result;
                }
            }
            return null;
        }
    }
}
